#ifndef	FRAME_BUFFER
#define	FRAME_BUFFER

#ifdef	_WIN32
	#include	<windows.h>
#endif

#ifdef	MACOSX
	#include	<OpenGL/gl.h>
#else
	#include	<GL/gl.h>
	#include	"../../GL/libExt/glext.h"
	#include	"../../GL/libExt/libExt.h"
    #include "Interfaces/ITexture.h"
#endif
namespace gname
{
class	FrameBuffer
{
	int		flags;
	int		width;
	int		height;
	GLuint	frameBuffer;					// id of framebuffer object
	GLuint	colorBuffer [8];				// texture id or buffer id
	GLuint	depthBuffer;
	GLuint	stencilBuffer;					// 
	GLint	saveViewport [4];				// saved viewport setting during bind
	
public:
	FrameBuffer  ( int theWidth, int theHeight, int theFlags = 0 );
	FrameBuffer(){}
	~FrameBuffer ();
	
	void setParameters(int theWidth, int theHeight, int theFlags = 0);
	
	int	GetWidth () const
	{
		return width;
	}
	
	int	GetHeight () const
	{
		return height;
	}
	
	bool	HasStencil () const
	{
		return stencilBuffer != 0;
	}
	
	bool	HasDepth () const
	{
		return depthBuffer != 0;
	}
	
	unsigned	GetColorBuffer ( int no = 0 ) const
	{
		return colorBuffer [no];
	}

	unsigned	GetDepthBuffer () const
	{
		return depthBuffer;
	}

	bool	IsOk     () const;
	bool	Create   ();
	bool	Bind     ();
	bool	BindFace ( int no );
	bool	Unbind   ( bool genMipmaps = false,  GLenum target = GL_TEXTURE_2D );
	
	bool	AttachColorTexture   ( GLenum target, unsigned texId, int no = 0 );
	bool	AttachDepthTexture   ( GLenum target, unsigned texId );
	bool	Attach3DTextureSlice ( unsigned texId, int zOffs, int no = 0 );
	
	bool	DetachColorTexture ( GLenum target )
	{
		return AttachColorTexture ( target, 0 );
	}
	
	bool	DetachDepthTexture ( GLenum target )
	{
		return AttachDepthTexture ( target, 0 );
	}
	
										// create texture for attaching 
	unsigned	CreateColorTexture     ( GLenum format = GL_RGBA, GLenum internalFormat = GL_RGBA8, 
	                                     GLenum clamp = GL_REPEAT, int filter = filterLinear );
										 
	unsigned	CreateColorRectTexture ( GLenum format = GL_RGBA, GLenum internalFormat = GL_RGBA8 );
	
	unsigned	CreateCubemapTexture   ( GLenum format = GL_RGBA, GLenum internalFormat = GL_RGBA8, 
	                                     GLenum clamp = GL_CLAMP_TO_EDGE, int filter = filterLinear );
										 
	unsigned	Create3DTexture       ( int depth, GLenum format = GL_RGBA, GLenum internalFormat = GL_RGBA8, 
	                                    GLenum clamp = GL_REPEAT, int filter = filterLinear );
										
										// mipmapping support
	void	BuildMipmaps ( GLenum target = GL_TEXTURE_2D ) const
	{
										// be sure we're unbound
		glBindTexture       ( target, GetColorBuffer () );
		glGenerateMipmapEXT ( target );
	}
	
	enum								// flags for depth and stencil buffers
	{
		depth16 = 1,					// 16-bit depth buffer
		depth24 = 2,					// 24-bit depth buffer
		depth32 = 4,					// 32-bit depth buffer
		
		stencil1  = 16,					// 1-bit stencil buffer
		stencil4  = 32,					// 4-bit stencil buffer
		stencil8  = 64,					// 8-bit stencil buffer
		stencil16 = 128					// 16-bit stencil buffer
	};
	
	enum								// filter modes
	{
		filterNearest = 0,
		filterLinear  = 1,
		filterMipmap  = 2
	};
	
	static	bool	IsSupported         ();
	static	int		MaxColorAttachemnts ();
	static	int		MaxSize             ();
};
}
#endif
